import tkinter as tk
from tkinter import ttk, messagebox
import threading
from getTargetPlan import Solution


DS = {
    "bg": "#f3f6fb",
    "card": "#ffffff",
    "primary": "#5b6cff",
    "accent": "#06b6d4",
    "text": "#0f172a",
    "sub": "#475569",
    "border": "#e6eef8",
    "radius": 12,
    "font": "Segoe UI",
}


class ScrollableFrame(ttk.Frame):

    def __init__(self, parent, **kw):
        super().__init__(parent)
        self.canvas = tk.Canvas(self, bg=DS["card"], bd=0, highlightthickness=0)
        self.scroll = ttk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.inner = ttk.Frame(self.canvas)
        self.inner_id = self.canvas.create_window(
            (0, 0), window=self.inner, anchor="nw"
        )
        self.canvas.configure(yscrollcommand=self.scroll.set)
        self.canvas.pack(side="left", fill="both", expand=True)
        self.scroll.pack(side="right", fill="y")
        self.inner.bind("<Configure>", self._on_configure)
        self.canvas.bind("<Configure>", self._on_canvas)

    def _on_configure(self, e=None):
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def _on_canvas(self, e=None):
        self.canvas.itemconfigure(self.inner_id, width=self.canvas.winfo_width())


class ModernEntry(ttk.Frame):
    def __init__(self, parent, label, default="", **kw):
        super().__init__(parent)
        ttk.Label(self, text=label, foreground=DS["sub"]).pack(anchor="w")
        self.var = tk.StringVar(value=default)
        ent = ttk.Entry(self, textvariable=self.var)
        ent.pack(fill="x", pady=(6, 0))
        self.entry = ent


class ModernGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("金额组合优化器")
        self.root.geometry("960x660")
        self.root.configure(bg=DS["bg"])
        self.root.title("金额组合优化器")
        self.root.geometry("820x480")
        app = tk.Frame(root, bg=DS["bg"])
        app.pack(fill="both", expand=True, padx=18, pady=18)

        top = tk.Frame(
            app,
            bg=DS["card"],
            height=56,
            bd=0,
            highlightthickness=1,
            highlightbackground=DS["border"],
        )
        top.pack(fill="x")
        tk.Label(
            top,
            text="金额组合优化器",
            bg=DS["card"],
            fg=DS["text"],
            font=(DS["font"], 14, "bold"),
        ).pack(side="left", padx=16)
        body = tk.Frame(app, bg=DS["bg"])
        body.pack(fill="both", expand=True, pady=(12, 0))

        left = tk.Frame(
            body,
            bg=DS["card"],
            width=360,
            bd=0,
            highlightthickness=1,
            highlightbackground=DS["border"],
        )
        left.pack(side="left", fill="y", padx=(0, 16))
        left.pack_propagate(False)
        tk.Label(
            left, text="快速从众多金额中抽出最优组合方案", bg=DS["card"], fg=DS["sub"]
        ).pack(anchor="w", pady=14, padx=16)

        self.e_money = ModernEntry(left, "金额列表（空格分隔）")
        self.e_money.pack(fill="x", padx=16)
        self.e_target = ModernEntry(left, "目标金额")
        self.e_target.pack(fill="x", padx=16)
        self.e_gap = ModernEntry(left, "差值范围", default="10")
        self.e_gap.pack(fill="x", padx=16)
        self.e_num = ModernEntry(left, "方案数量", default="3")
        self.e_num.pack(fill="x", padx=16)
        self.start_btn = tk.Button(
            left,
            text="开始组合",
            bg=DS["primary"],
            fg="#fff",
            bd=0,
            activebackground=DS["primary"],
            relief="flat",
            command=lambda: threading.Thread(target=self.run, daemon=True).start(),
        )
        self.start_btn.pack(fill="x", padx=16, pady=18)
        self.start_btn.bind("<Enter>", lambda e: self.start_btn.config(bg="#4656df"))
        self.start_btn.bind(
            "<Leave>", lambda e: self.start_btn.config(bg=DS["primary"])
        )

        right = tk.Frame(
            body,
            bg=DS["card"],
            bd=0,
            highlightthickness=1,
            highlightbackground=DS["border"],
        )
        right.pack(side="right", fill="both", expand=True)
        head = tk.Frame(right, bg=DS["card"])
        head.pack(fill="x", pady=12, padx=12)
        tk.Label(
            head,
            text="组合结果",
            bg=DS["card"],
            fg=DS["text"],
            font=(DS["font"], 14, "bold"),
        ).pack(side="left")
        tk.Button(
            head, text="📋 复制", bg=DS["card"], bd=0, command=self.copy_result
        ).pack(side="right")

        self.results = ScrollableFrame(right)
        self.results.pack(fill="both", expand=True, padx=12, pady=(0, 12))

        self.empty_state()

    def run(self):
        try:
            money_list = list(map(float, self.e_money.var.get().strip().split()))
            target = float(self.e_target.var.get())
            gap = float(self.e_gap.var.get() or 10)
            num = int(self.e_num.var.get() or 3)
        except Exception as e:
            messagebox.showerror("输入错误", f"请检查输入格式：{e}")
            return

        sol = Solution(gap=gap, targetMoney=target)
        res = sol.exe(money_list)
        sorted_res = sorted(res, key=lambda x: x.money, reverse=True)
        self.show_results(sorted_res, target, num)

    def clear_results(self):
        for w in self.results.inner.winfo_children():
            w.destroy()

    def show_results(self, results, target, limit):
        self.clear_results()
        if not results:
            self.empty_state()
            return
        for i, p in enumerate(results):
            if i >= limit:
                break
            card = tk.Frame(
                self.results.inner,
                bg=DS["card"],
                bd=0,
                highlightthickness=1,
                highlightbackground=DS["border"],
            )
            card.pack(fill="x", padx=12, pady=8)
            top = tk.Frame(card, bg=DS["card"])
            top.pack(fill="x", padx=12, pady=8)
            tk.Label(
                top,
                text=f"总金额: {p.money}",
                bg=DS["card"],
                fg=DS["primary"],
                font=(DS["font"], 12, "bold"),
            ).pack(side="left")
            tk.Label(
                top,
                text=f"差值: {target - p.money}",
                bg=DS["card"],
                fg=DS["sub"],
            ).pack(side="right")
            tk.Label(card, text=f"方案: {p.plan}", bg=DS["card"], fg=DS["text"]).pack(
                fill="x", padx=12, pady=(0, 12)
            )

    def empty_state(self):
        self.clear_results()
        placeholder = tk.Frame(self.results.inner, bg=DS["card"])
        placeholder.pack(fill="both", expand=True, padx=12, pady=24)
        tk.Label(placeholder, text="暂无结果", bg=DS["card"], fg=DS["sub"]).pack(
            pady=24
        )

    def copy_result(self):
        parts = []
        for card in self.results.inner.winfo_children():
            for w in card.winfo_children():
                if isinstance(w, tk.Label):
                    parts.append(w.cget("text"))
        txt = "\n".join(parts)
        self.root.clipboard_clear()
        self.root.clipboard_append(txt)
        messagebox.showinfo("提示", "结果已复制到剪贴板")


if __name__ == "__main__":
    root = tk.Tk()
    ModernGUI(root)
    root.mainloop()
